/**
 * Copyright (C) 2012  ARToolkitPlus Benchmark Authors
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *  Hirokazu Kato
 *  Daniel Wagner
 *  Pavel Rojtberg
 *  Tobias Domhan
 *  Krzysztof Skrzypski
 */

package com.artollkitplus.benchmark;

import java.io.IOException;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.text.TextPaint;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.SurfaceHolder.Callback;
import android.widget.FrameLayout;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ARActivity extends Activity implements Callback{
	private GLSurfaceView glSurfaceView;
	public Camera camera;
	private OpenGLCamRenderer renderer;
	private Resources res;
	private CameraPreviewHandler cameraHandler;
	private SurfaceHolder sHolder;
	private MarkerInfo markerInfo;
	private static String TAG = "ARActivity";
	private int onMenuItemSelectedCount = 0;//for Android 1.5, to hold pause on submenus 

	//submenus
	private SubMenu mode_ar_library;
	private SubMenu image_size;
	private SubMenu mode_image;
	private SubMenu mode_marker_type;
	private SubMenu mode_pose_estimator;
	private SubMenu mode_tracker_base_type;
	private SubMenu mode_Hull;
	private SubMenu other;
		
	private Preview previewSurface;
	
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);      
        res = getResources();  
        CurrentConfig.SDCARD_AVAILABLE = IO.isSdcardAvailable();
        if(CurrentConfig.SDCARD_AVAILABLE){
        	IO.transferFilesToSDCard(res);
        }else{
        	Log.e(TAG, "SDCARD is not available");
        }
        CurrentConfig.updateConfigurationString();
        markerInfo = new MarkerInfo(this);
        glSurfaceView = new GLSurfaceView(this);
		renderer = new OpenGLCamRenderer(res, markerInfo);
		cameraHandler = new CameraPreviewHandler(glSurfaceView, renderer, res, markerInfo);
        glSurfaceView.setRenderer(renderer);
        glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
        
        previewSurface = new Preview(this);
        sHolder = glSurfaceView.getHolder();
        //sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        sHolder.addCallback(this);
        DrawOnTop  topLayer = new DrawOnTop(this);
        FrameLayout r1 = new FrameLayout(this.getApplicationContext());
        setContentView(r1);
        r1.addView(glSurfaceView);
        r1.addView(previewSurface);
        r1.addView(topLayer);
    }

    protected void onPause() {
    	super.onPause();
        this.glSurfaceView.onPause();
        
    }
    
    protected void onResume() {
    	super.onResume();
    	glSurfaceView.onResume();
    }
    
    protected void onStop() {
    	super.onStop();
    	this.finish();  
    }
    
    private void openCamera(SurfaceHolder holder)  {
    	if (camera == null) {
            try {
            	camera = android.hardware.Camera.open();
            } catch (RuntimeException e) {
                Log.e(TAG, "Failed to open Camera", e);
            }
	        Parameters params = camera.getParameters();
	        params.setPreviewSize(CurrentConfig.DEFAULT_IMAGE_WIDTH,CurrentConfig.DEFAULT_IMAGE_HEIGT);
	        camera.setParameters(params);
	        camera.setPreviewCallback(cameraHandler);
	        try {
				camera.setPreviewDisplay(holder);
			} catch (IOException e1) {
				e1.printStackTrace();
			}
	        try {
				cameraHandler.init(camera);
			} catch (Exception e) {
				Log.e(TAG, "Camera init failed");
			}
    	}
    }
    
    private static Method mGetSupportedPreviewSizes;
    static{
    	try {
            mGetSupportedPreviewSizes = android.hardware.Camera.Parameters.class.getMethod("getSupportedPreviewSizes", (Class[]) null);
        } catch (NoSuchMethodException e) {}
    }


    @SuppressWarnings("unchecked")
	public static List<android.hardware.Camera.Size> getSupportedPreviewSizes(android.hardware.Camera.Parameters parameters) {
        if (mGetSupportedPreviewSizes == null)
            return null;

        try {
            return (List<android.hardware.Camera.Size>) mGetSupportedPreviewSizes.invoke(parameters, (Object[]) null);
        } catch (IllegalAccessException e) {
            Log.e(TAG, "couldnt call getSupportedPreviewSizes "+e);
            return null;
        } catch (InvocationTargetException e) {
            Log.e(TAG, "couldnt call getSupportedPreviewSizes " + e);
            return null;
        }
    }
    
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
		if(camera!=null){
			if(mGetSupportedPreviewSizes!=null){
				Camera.Parameters parameters = camera.getParameters();
			    List<Size> supportedPreviewSizes = getSupportedPreviewSizes(parameters);
			    Size optimalPreviewSize = CameraPreviewHandler.getOptimalPreviewSize(supportedPreviewSizes, width, height);
			    if (optimalPreviewSize != null) {
			    	parameters.setPreviewSize(optimalPreviewSize.width, optimalPreviewSize.height);
			        CurrentConfig.OPTIMAL_IMAGE_WIDTH = optimalPreviewSize.width;
			        CurrentConfig.OPTIMAL_IMAGE_HEIGT = optimalPreviewSize.height;
			        camera.setParameters(parameters);	        
			    }
			}
		}

	}

	public void surfaceCreated(SurfaceHolder holder) {
		openCamera(holder);
	}

	public void surfaceDestroyed(SurfaceHolder holder) {
		if (camera != null) {
                     camera.stopPreview();
		}
	}

	public boolean onCreateOptionsMenu(Menu menu) {
		mode_ar_library = menu.addSubMenu(Config._MENU_GROUP_ONE, Config._MODE_AR_LIBRARY, Config.ORDER_BEFORE_EXIT, R.string._mode_ar_library);
		mode_ar_library.add(0, Config.MODE_AR_ARTOOLKIT, 0, R.string.mode_ar_library_artoolkit);
		mode_ar_library.add(0, Config.MODE_AR_ARTOOLKIT_PLUS, 0, R.string.mode_ar_library_artoolkit_plus);
    	
		mode_image = menu.addSubMenu(Config._MENU_GROUP_ONE, Config._MODE_IMAGE, Config.ORDER_BEFORE_EXIT, R.string._mode_image);
		mode_image.add(0, Config.MODE_IMAGE_RGB, 0, res.getText(R.string.mode_image_rgb));
		mode_image.add(0, Config.MODE_IMAGE_GRAY, 0, res.getText(R.string.mode_image_gray));
		
		image_size = menu.addSubMenu(Config._MENU_GROUP_ONE, Config._IMAGE_SIZE, Config.ORDER_BEFORE_EXIT, R.string._image_size);
		image_size.add(0, Config.IMAGE_SIZE_OPTIMAL, 0, res.getText(R.string.image_size_optimal));
		image_size.add(0, Config.IMAGE_SIZE_800x480, 0, res.getText(R.string.image_size_800x480));
		image_size.add(0, Config.IMAGE_SIZE_480x320, 0, res.getText(R.string.image_size_480x320));
		image_size.add(0, Config.IMAGE_SIZE_320x240, 0, res.getText(R.string.image_size_320x240));
		image_size.add(0, Config.IMAGE_SIZE_300x225, 0, res.getText(R.string.image_size_300x225));
		image_size.add(0, Config.IMAGE_SIZE_280x210, 0, res.getText(R.string.image_size_280x210));
		image_size.add(0, Config.IMAGE_SIZE_260x195, 0, res.getText(R.string.image_size_260x195));
		image_size.add(0, Config.IMAGE_SIZE_240x180, 0, res.getText(R.string.image_size_240x180));
		image_size.add(0, Config.IMAGE_SIZE_220x165, 0, res.getText(R.string.image_size_220x165));
		image_size.add(0, Config.IMAGE_SIZE_200x150, 0, res.getText(R.string.image_size_200x150));
		image_size.add(0, Config.IMAGE_SIZE_180x135, 0, res.getText(R.string.image_size_180x135));
		image_size.add(0, Config.IMAGE_SIZE_160x120, 0, res.getText(R.string.image_size_160x120));
		image_size.add(0, Config.IMAGE_SIZE_140x105, 0, res.getText(R.string.image_size_140x105));
		image_size.add(0, Config.IMAGE_SIZE_120x90, 0, res.getText(R.string.image_size_120x90));
	    
		mode_marker_type = menu.addSubMenu(Config._MENU_GROUP_TWO, Config._MODE_MARKER_TYPE, Config.ORDER_BEFORE_EXIT, R.string._mode_marker_type);
		mode_marker_type.add(0, Config.MODE_MARKER_TYPE_TEMPLATE, 0, res.getText(R.string.mode_marker_type_template));
		mode_marker_type.add(0, Config.MODE_MARKER_TYPE_SIMPLE, 0, res.getText(R.string.mode_marker_type_simple));
		mode_marker_type.add(0, Config.MODE_MARKER_TYPE_BCH, 0, res.getText(R.string.mode_marker_type_bch));

		mode_pose_estimator = menu.addSubMenu(Config._MENU_GROUP_TWO, Config._MODE_POSE_ESTIMATOR, Config.ORDER_AFTER_EXIT, R.string._mode_pose_estimator);
		mode_pose_estimator.add(0, Config.MODE_POSE_ESTIMATOR_ORIGINAL, 0, res.getText(R.string.mode_pose_estimator_original));
		mode_pose_estimator.add(0, Config.MODE_POSE_ESTIMATOR_ORIGINAL_CONT, 0, res.getText(R.string.mode_pose_estimator_original_cont));
		mode_pose_estimator.add(0, Config.MODE_POSE_ESTIMATOR_RPP, 0, res.getText(R.string.mode_pose_estimator_rpp));

		mode_tracker_base_type = menu.addSubMenu(Config._MENU_GROUP_TWO, Config._MODE_TRACKER_BASE_TYPE, Config.ORDER_AFTER_EXIT, R.string._mode_tracker_base_type);
		mode_tracker_base_type.add(0, Config.MODE_TRACKER_BASE_TYPE_SINGLE, 0, res.getText(R.string.mode_tracker_base_type_single));
		mode_tracker_base_type.add(0, Config.MODE_TRACKER_BASE_TYPE_MULTI, 0, res.getText(R.string.mode_tracker_base_type_multi));
		
		mode_Hull = menu.addSubMenu(Config._MENU_GROUP_THREE, Config._MODE_HULL, Config.ORDER_AFTER_EXIT, R.string._mode_Hull);
		mode_Hull.add(0, Config.MODE_HULL_OFF, 0, res.getText(R.string.mode_hull_off));
		mode_Hull.add(0, Config.MODE_HULL_FOUR, 0, res.getText(R.string.mode_hull_four));
		mode_Hull.add(0, Config.MODE_HULL_FULL, 0, res.getText(R.string.mode_hull_full));
		
		other = menu.addSubMenu(0, Config._OTHER, Config.ORDER_AFTER_EXIT, R.string.other);
		other.add(0, Config.SHOW_CONFIGURATION, 0, res.getText(R.string.show_configuration));
		other.add(0, Config.PAUSE_SCREEN, 0, res.getText(R.string.pause_screen));
		other.add(0, Config.SHOW_FPS, 0, res.getText(R.string.show_fps));
	    
		menu.add(0, Config.EXIT_APP, Config.ORDER_EXIT, R.string.exit_app);
		
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		int tmpItemId = item.getItemId();
		switch (tmpItemId) {
			case Config.EXIT_APP:
				camera.stopPreview();
				camera.release();
				System.exit(1);
				break;
			case Config.MODE_AR_ARTOOLKIT:	
				CurrentConfig.CURRENT_MENU_GROUP_SETTINGS&=Config.BIT_GROUP_ARTOOLKIT_CLEAR_MASK;
				CurrentConfig.CURRENT_MENU_GROUP_SETTINGS |= Config.BIT_GROUP_ARTOOLKIT;
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_MODE_AR_ARTOOLKIT_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_MODE_AR_ARTOOLKIT;
				break;
			case Config.MODE_AR_ARTOOLKIT_PLUS:
				CurrentConfig.CURRENT_MENU_GROUP_SETTINGS&=Config.BIT_GROUP_ARTOOLKIT_CLEAR_MASK;
				CurrentConfig.CURRENT_MENU_GROUP_SETTINGS |= Config.BIT_GROUP_ARTOOLKIT_PLUS;
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_MODE_AR_ARTOOLKIT_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_MODE_AR_ARTOOLKIT_PLUS;
				break;	
			case Config.MODE_TRACKER_BASE_TYPE_SINGLE:
				CurrentConfig.CURRENT_MENU_GROUP_SETTINGS&=Config.BIT_GROUP_ARTOOLKIT_PLUS_CLEAR_MASK;
				CurrentConfig.CURRENT_MENU_GROUP_SETTINGS |= Config.BIT_GROUP_ARTOOLKIT_PLUS_SINGLE;
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_MODE_TRACKER_BASE_TYPE_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_MODE_TRACKER_BASE_TYPE_SINGLE;
				setCameraNewParameters(CurrentConfig.DEFAULT_IMAGE_WIDTH,CurrentConfig.DEFAULT_IMAGE_HEIGT);
				break;
			case Config.MODE_TRACKER_BASE_TYPE_MULTI:
				CurrentConfig.CURRENT_MENU_GROUP_SETTINGS&=Config.BIT_GROUP_ARTOOLKIT_PLUS_CLEAR_MASK;
				CurrentConfig.CURRENT_MENU_GROUP_SETTINGS |= Config.BIT_GROUP_ARTOOLKIT_PLUS_MULTI;
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_MODE_TRACKER_BASE_TYPE_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_MODE_TRACKER_BASE_TYPE_MULTI;
				setCameraNewParameters(CurrentConfig.DEFAULT_IMAGE_WIDTH,CurrentConfig.DEFAULT_IMAGE_HEIGT);
				break;
			case Config.MODE_IMAGE_RGB:
				CurrentConfig.CURRENT_IMAGE_SETTINGS&=CurrentConfig.BIT_MODE_IMAGE_CLEAR_MASK;
				CurrentConfig.CURRENT_IMAGE_SETTINGS|= Config.BIT_MODE_IMAGE_RGB;
				this.cameraHandler.setMode(tmpItemId);
				break;
			case Config.MODE_IMAGE_GRAY:
				CurrentConfig.CURRENT_IMAGE_SETTINGS&=CurrentConfig.BIT_MODE_IMAGE_CLEAR_MASK;
				CurrentConfig.CURRENT_IMAGE_SETTINGS|= Config.BIT_MODE_IMAGE_GRAY;
				this.cameraHandler.setMode(tmpItemId);
				break;
			case Config.IMAGE_SIZE_320x240:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_IMAGE_SIZE_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_IMAGE_SIZE_320x240;
		        setCameraNewParameters(320,240);
				break;
			case Config.IMAGE_SIZE_300x225:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_IMAGE_SIZE_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_IMAGE_SIZE_300x225;
		        setCameraNewParameters(300,225);
				break;
			case Config.IMAGE_SIZE_280x210:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_IMAGE_SIZE_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_IMAGE_SIZE_280x210;
				setCameraNewParameters(280,210);
				break;
			case Config.IMAGE_SIZE_260x195:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_IMAGE_SIZE_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_IMAGE_SIZE_260x195;
				setCameraNewParameters(260,195);
				break;
			case Config.IMAGE_SIZE_240x180:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_IMAGE_SIZE_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_IMAGE_SIZE_240x180;
				setCameraNewParameters(240,180);
				break;
			case Config.IMAGE_SIZE_220x165:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_IMAGE_SIZE_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_IMAGE_SIZE_220x165;
				setCameraNewParameters(220,165);
				break;
			case Config.IMAGE_SIZE_200x150:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_IMAGE_SIZE_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_IMAGE_SIZE_200x150;
				setCameraNewParameters(200,150);
				break;
			case Config.IMAGE_SIZE_180x135:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_IMAGE_SIZE_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_IMAGE_SIZE_180x135;
				setCameraNewParameters(180,135);
				break;
			case Config.IMAGE_SIZE_160x120:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_IMAGE_SIZE_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_IMAGE_SIZE_160x120;
				setCameraNewParameters(160,120);
				break;
			case Config.IMAGE_SIZE_140x105:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_IMAGE_SIZE_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_IMAGE_SIZE_140x105;
				setCameraNewParameters(140,105);
				break;
			case Config.IMAGE_SIZE_120x90:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_IMAGE_SIZE_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_IMAGE_SIZE_120x90;
				setCameraNewParameters(120,90);
				break;
			
			case Config.IMAGE_SIZE_OPTIMAL:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_IMAGE_SIZE_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_IMAGE_SIZE_OPTIMAL;
				setCameraNewParameters(CurrentConfig.OPTIMAL_IMAGE_WIDTH,CurrentConfig.OPTIMAL_IMAGE_HEIGT);
				break;
			case Config.IMAGE_SIZE_800x480:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_IMAGE_SIZE_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_IMAGE_SIZE_800x480;
				setCameraNewParameters(800,480);
				break;
			case Config.IMAGE_SIZE_480x320:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_IMAGE_SIZE_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_IMAGE_SIZE_480x320;
				setCameraNewParameters(480,320);
				break;	
			
			case Config.MODE_MARKER_TYPE_TEMPLATE:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_MODE_MARKER_TYPE_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_MODE_MARKER_TYPE_TEMPLATE;
				setCameraNewParameters(CurrentConfig.DEFAULT_IMAGE_WIDTH,CurrentConfig.DEFAULT_IMAGE_HEIGT);
				break;
			case Config.MODE_MARKER_TYPE_SIMPLE:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_MODE_MARKER_TYPE_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_MODE_MARKER_TYPE_SIMPLE;
				setCameraNewParameters(CurrentConfig.DEFAULT_IMAGE_WIDTH,CurrentConfig.DEFAULT_IMAGE_HEIGT);
				break;
			case Config.MODE_MARKER_TYPE_BCH:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_MODE_MARKER_TYPE_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_MODE_MARKER_TYPE_BCH;
				setCameraNewParameters(CurrentConfig.DEFAULT_IMAGE_WIDTH,CurrentConfig.DEFAULT_IMAGE_HEIGT);
				break;
			case Config.MODE_POSE_ESTIMATOR_ORIGINAL:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_MODE_POSE_ESTIMATOR_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_MODE_POSE_ESTIMATOR_ORIGINAL;
				setCameraNewParameters(CurrentConfig.DEFAULT_IMAGE_WIDTH,CurrentConfig.DEFAULT_IMAGE_HEIGT);
				break;
			case Config.MODE_POSE_ESTIMATOR_ORIGINAL_CONT:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_MODE_POSE_ESTIMATOR_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_MODE_POSE_ESTIMATOR_ORIGINAL_CONT;
				setCameraNewParameters(CurrentConfig.DEFAULT_IMAGE_WIDTH,CurrentConfig.DEFAULT_IMAGE_HEIGT);
				break;
			case Config.MODE_POSE_ESTIMATOR_RPP:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_MODE_POSE_ESTIMATOR_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_MODE_POSE_ESTIMATOR_RPP;
				setCameraNewParameters(CurrentConfig.DEFAULT_IMAGE_WIDTH,CurrentConfig.DEFAULT_IMAGE_HEIGT);
				break;
			case Config.MODE_HULL_OFF:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_MODE_HULL_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_MODE_HULL_OFF;
				setCameraNewParameters(CurrentConfig.DEFAULT_IMAGE_WIDTH,CurrentConfig.DEFAULT_IMAGE_HEIGT);
				break;
			case Config.MODE_HULL_FOUR:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_MODE_HULL_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_MODE_HULL_FOUR;
				setCameraNewParameters(CurrentConfig.DEFAULT_IMAGE_WIDTH,CurrentConfig.DEFAULT_IMAGE_HEIGT);
				break;
			case Config.MODE_HULL_FULL:
				CurrentConfig.CURRENT_AR_SETTINGS&=Config.BIT_MODE_HULL_CLEAR_MASK;
				CurrentConfig.CURRENT_AR_SETTINGS |= Config.BIT_MODE_HULL_FULL;
				setCameraNewParameters(CurrentConfig.DEFAULT_IMAGE_WIDTH,CurrentConfig.DEFAULT_IMAGE_HEIGT);
				break;
			case Config.SHOW_CONFIGURATION:
				CurrentConfig.SHOW_CONFIGURATION=!CurrentConfig.SHOW_CONFIGURATION;
				break;
			case Config.PAUSE_SCREEN:
				CurrentConfig.USE_MENU_PAUSE_SCREEN=!CurrentConfig.USE_MENU_PAUSE_SCREEN;
				pauseMenuOn(false);
				break;
			case Config.SHOW_FPS:
				CurrentConfig.SHOW_FPS=!CurrentConfig.SHOW_FPS;
				break;
				
		}
		CurrentConfig.updateConfigurationString();
		if(onMenuItemSelectedCount>0){//Android 1.5
			pauseMenuOn(false);
		}
		onMenuItemSelectedCount++;//Android 1.5
		return true;
	}

	private void pauseMenuOn(boolean on){//Android 1.5
		if(on){
			CurrentConfig.MENU_PAUSE_SCREEN_ON = true;
			camera.stopPreview();
		}else{
			CurrentConfig.MENU_PAUSE_SCREEN_ON = false;
			camera.startPreview();
		}
	}
	
	private void setCameraNewParameters(int w,int h){
		renderer.isTextureInitialized = false;
		Parameters params = camera.getParameters();
		params.setPreviewSize(w,h);
        camera.setParameters(params);
        try {
			cameraHandler.init(camera);
		} catch (Exception e) {
			Log.e(TAG, "Camera init failed");
		} 
	}

	public boolean onMenuOpened(int featureId, Menu menu) {
		pauseMenuOn(true);
		return super.onMenuOpened(featureId, menu);
	}

	public boolean onPrepareOptionsMenu(Menu menu) {
		onMenuItemSelectedCount = 0;//Android 1.5
		
		if((CurrentConfig.CURRENT_MENU_GROUP_SETTINGS&Config.MODE_AR_ARTOOLKIT)>0){
			menu.setGroupEnabled(Config._MENU_GROUP_ONE, true);
			menu.setGroupEnabled(Config._MENU_GROUP_TWO, false);
			menu.setGroupEnabled(Config._MENU_GROUP_THREE, false);
		}
		if((CurrentConfig.CURRENT_MENU_GROUP_SETTINGS&Config.MODE_AR_ARTOOLKIT_PLUS)>0){
			menu.setGroupEnabled(Config._MENU_GROUP_ONE, true);
			menu.setGroupEnabled(Config._MENU_GROUP_TWO, true);
			if((CurrentConfig.CURRENT_MENU_GROUP_SETTINGS&Config.BIT_GROUP_ARTOOLKIT_PLUS_MULTI)>0){
				menu.setGroupEnabled(Config._MENU_GROUP_THREE, true);
			}else{
				menu.setGroupEnabled(Config._MENU_GROUP_THREE, false);
			}
		}
		return super.onPrepareOptionsMenu(menu);
	}

	public void onOptionsMenuClosed(Menu menu) {
		pauseMenuOn(false);
		super.onOptionsMenuClosed(menu);
	}

	class DrawOnTop extends View {
		private int commonFontSize = 16;
		private int commonOffsetSize = 2;
		
		private int fpsTextSize = 25;
		private int fpsOffsetX = 10;
		private int fpsOffsetY = fpsTextSize+commonOffsetSize;
		private int avgFpsTextSize = commonFontSize;
		private int avgFpsOffsetY = fpsOffsetY+avgFpsTextSize+commonOffsetSize;
		private int currFrameSizeTextSize = commonFontSize;
		private int currFrameSizeOffsetY = avgFpsOffsetY+currFrameSizeTextSize+commonOffsetSize;
		private int avgFrameSizeTextSize = commonFontSize;
		private int avgFrameSizeOffsetY = currFrameSizeOffsetY+avgFrameSizeTextSize+commonOffsetSize;
		private int timeNativeMarkerDetectionTextSize = commonFontSize;
		private int timeNativeMarkerDetectionOffsetY = avgFrameSizeOffsetY+timeNativeMarkerDetectionTextSize+commonOffsetSize;
		private int avgNativeMarkerDetectionTextSize = commonFontSize;
		private int avgNativeMarkerDetectionOffsetY = timeNativeMarkerDetectionOffsetY+avgNativeMarkerDetectionTextSize+commonOffsetSize;
		private int timeJavaMarkerDetectionTextSize = commonFontSize;
		private int timeJavaMarkerDetectionOffsetY = avgNativeMarkerDetectionOffsetY+timeJavaMarkerDetectionTextSize+commonOffsetSize;
		private int avgJavaMarkerDetectionTextSize = commonFontSize;
		private int avgJavaMarkerDetectionOffsetY = timeJavaMarkerDetectionOffsetY+avgJavaMarkerDetectionTextSize+commonOffsetSize;
		private int configTextSize = 10;
		private int configOffsetX = 10;
		private int configOffsetY = avgJavaMarkerDetectionOffsetY+configTextSize+commonOffsetSize;
		Paint paint = new Paint();
		TextPaint textPaint = new TextPaint();
		
		public DrawOnTop(Context context) {
			super(context);
			paint.setStyle(Paint.Style.FILL);
			paint.setColor(Color.GREEN);
			paint.setTextSize(fpsTextSize);
		}
		
		protected void onDraw(Canvas canvas) {	
			if (CurrentConfig.SHOW_FPS) {
				paint.setTextSize(fpsTextSize);
				canvas.drawText("FPS: "+DebugFps._fps, fpsOffsetX, fpsOffsetY, paint);
				paint.setTextSize(avgFpsTextSize);
				canvas.drawText("AVG FPS: "+DebugFps._avg_fps, fpsOffsetX, avgFpsOffsetY, paint);
				canvas.drawText("Time taken: "+DebugFps.currFrameTime, fpsOffsetX, currFrameSizeOffsetY, paint);
				canvas.drawText("Avg time taken: "+DebugFps.avgFrameTime, fpsOffsetX, avgFrameSizeOffsetY, paint);
				canvas.drawText("Native marker detect: "+MarkerInfo.timeNativeMarkerDetection, fpsOffsetX, timeNativeMarkerDetectionOffsetY, paint);
				canvas.drawText("Avg native marker detect: "+MarkerInfo.avgNativeMarkerDetection, fpsOffsetX, avgNativeMarkerDetectionOffsetY, paint);
				canvas.drawText("Java marker detect: "+MarkerInfo.timeJavaMarkerDetection, fpsOffsetX, timeJavaMarkerDetectionOffsetY, paint);
				canvas.drawText("Avg Java marker detect: "+MarkerInfo.avgJavaMarkerDetection, fpsOffsetX, avgJavaMarkerDetectionOffsetY, paint);
			}
			if(CurrentConfig.SHOW_CONFIGURATION){
				canvas.translate(configOffsetX,configOffsetY); 
				CurrentConfig.TEXT_LAYOUT.draw(canvas);
			}
			invalidate();
		}
	}
	
	//walkaround for Issue 214: EGL_BAD_ALLOC on Android 2.3.x
	class Preview extends SurfaceView implements SurfaceHolder.Callback {
	    SurfaceHolder localHolder;
	    
	    Preview(Context context) {
	        super(context);
	        localHolder = getHolder();
	        localHolder.addCallback(this);
	        localHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
	    }

	    public void surfaceCreated(SurfaceHolder holder) {
	    }

	    public void surfaceDestroyed(SurfaceHolder holder) {
	        sHolder = null;
	    }

	    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
	    	sHolder = holder;
	    	sHolder.addCallback(this);
	        try {
		    camera.setPreviewDisplay(holder);
		} catch (IOException e) {
		    e.printStackTrace();
		}
	        setCameraNewParameters(CurrentConfig.DEFAULT_IMAGE_WIDTH,CurrentConfig.DEFAULT_IMAGE_HEIGT);
    		camera.startPreview();
	    }  
	}
	
}